#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <math.h>

#define TYPE double
#define NUM_THREADS 2

// this test checks the performance of the sequential and parallel
// implementation.  This is done to check the performance characteristics
// with different sizes of input.


// the use must define this function to use genericScan
//void userBinaryOperator( void *x1, void *x2) {
//	TYPE *a = (TYPE *) x1;
//	TYPE *b = (TYPE *) x2;
//	
//	*a += *b;
//}

void seqScan(TYPE *X, unsigned int n, unsigned int offset, unsigned int stride);
void hybridScan(TYPE *X, int n, int blockBits, int dim);

// DRIVER
int main( int argc, char **argv) {	
	
	// problem setup
	int n = 30000000;
	int dim = 1;
	int i, m, j;
	double t1, t2;

	if(argc > 1) n = atoi(argv[1]);
	if(argc > 2) dim = atoi(argv[2]);
	TYPE *x = (TYPE *) malloc( sizeof(TYPE) * n * dim);
/*
*/

	for (m = 1; m < n; m *= 2) {
		//omp_set_nested(1);
		//omp_set_dynamic(1);

        for(i = 0; i < m; i++)
            for (j = 0; j < dim; j++)
                x[i * dim + j] = i % 2;

		t1 = omp_get_wtime(); 
		seqScan(x, m, 0, dim);
		t2 = omp_get_wtime();

		printf("\nseq:    dim = %d, keys = %d: %g secs\n", dim, m, t2-t1);

        for(i = 0; i < m; i++)
            for (j = 0; j < dim; j++)
                x[i * dim + j] = i % 2;

		t1 = omp_get_wtime(); 
		hybridScan(x, m, 13, dim);
		t2 = omp_get_wtime();
	
		printf("\nhybrid: dim = %d, keys = %d: %g secs\n", dim, m, t2-t1);
	}
	
	// clean up
	free(x);
	return 0;
}
	




	


	



